const router = require('koa-router')()
const { SuccessModul, ErrorModule } = require('../classes/result')
const { Order } = require('../classes/order')
const controller = require('../controller/order')
const EventEmitter = require('events')
const emitter = new EventEmitter();

const loginCheck = require('../middleware/login-check')

router.prefix('/api/order')

router.get('/list', loginCheck, async (ctx) => {
  const user = ctx.session.user
  try {
    const result = await controller.orderList(user)
    ctx.body = new SuccessModul(result)
  } catch (msg) {
    ctx.body = new ErrorModule(msg)
  }
})

router.post('/create', loginCheck, async (ctx) => {
  const { state, username } = ctx.session.user
  if (+state === 2) {
    ctx.body = new ErrorModule('快递员不得创建订单')
    return
  }

  const { senderName, senderPhone, senderAddress, 
    receiverName, receiverPhone, receiverAddress } = ctx.request.body
  const name = state === 3 ? senderName : username
  const order = new Order({
    senderName: name,
    senderPhone, 
    senderAddress, 
    receiverName, 
    receiverPhone, 
    receiverAddress 
  })
  try {
    const result = await controller.orderCreate(order)
    listNotifie(senderName, receiverName)
    ctx.body = new SuccessModul(result)
  } catch (msg) {
    ctx.body = new ErrorModule(msg)
  }
})

router.get('/detail', loginCheck, async (ctx) => {
  const user = ctx.session.user
  const id = ctx.query.id
  try {
    const result = await controller.orderDetail(id, user)
    ctx.body = new SuccessModul(result)
  } catch (msg) {
    ctx.body = new ErrorModule(msg)
  }
})

router.post('/delete', loginCheck, async (ctx) => {
  const user = ctx.session.user
  const { order } = ctx.request.body
  const id = order.id

  if (+user.state === 2) {
    ctx.body = new ErrorModule('快递员不得删除订单')
    return
  }

  try {
    const result = await controller.orderDelete(id, user)
    listNotifie(order.receiver.name, order.sender.name)
    ctx.body = new SuccessModul(result)
  } catch (msg) {
    ctx.body = new ErrorModule(msg)
  }
})

router.post('/updateState', loginCheck, async (ctx) => {
  const user = ctx.session.user
  const { order, state } = ctx.request.body

  if (state === 4) {
    if (user.state !== 3 && user.username !== order.receiver.name) {
      ctx.body = new ErrorModule('您不是订单收件人喔！')
      return
    }
    if (order.state === 4) {
      ctx.body = new ErrorModule('该订单已取件！')
      return
    }
  }
  if (+state !== 4 && +user.state < 2) {
    ctx.body = new ErrorModule('权限不足')
    return
  }

  try {
    const result = await controller.orderUpdateState(order.id, user, state)
    if (state === 4) {
      receiveNotifie(order.id)
    }
    listNotifie(order.receiver.name, order.sender.name)
    ctx.body = new SuccessModul(result)
  } catch (msg) {
    ctx.body = new ErrorModule(msg)
  }
})

router.post('/watchReceiver', loginCheck, async (ctx) => {
  const user = ctx.session.user
  const { orderId } = ctx.request.body
  if (user.state < 2) {
    ctx.body = new ErrorModule()
    return
  }
  try {
    await receiverWait(orderId)
    ctx.body = new SuccessModul()
  } catch {
    ctx.body = new ErrorModule()
  }
})
router.post('/closeWR', loginCheck, async (ctx) => {
  const { orderId } = ctx.request.body
  receiveClose(orderId)
  ctx.body = new SuccessModul()
})

router.post('/watchList', loginCheck, async (ctx) => {
  const user = ctx.session.user
  const name = user.state > 1 ? 'all' : user.username

  try {
    await listWait(name)
    ctx.body = new SuccessModul()
  } catch {
    ctx.body = new ErrorModule()
  }
})

module.exports = router

function receiveNotifie (orderId) {
  emitter.emit('received-' + orderId)
}
function receiveClose (orderId) {
  emitter.emit('rm-received-' + orderId)
}

function receiverWait (orderId) {
  return new Promise((resolve, reject) => {
    emitter.on('received-' + orderId, () => {
      resolve()
    })
    emitter.on('rm-received-' + orderId, () => {
      reject()
    })
  })
}

function listNotifie (...names) {
  emitter.emit('list-all')
  names.forEach(name => {
    emitter.emit('list-' + name)
  })
}
function listWait (name) {
  return new Promise((resolve) => {
    emitter.on('list-' + name, (msg) => {
      resolve(msg)
    })
  })
}